package dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

public class BaseDAO {
	public static final String DEFAULT_NAME = "jdbc/trkj";
	
	private String contextName;//连接池的名称

	public BaseDAO() {
		this(DEFAULT_NAME);
	}

	public BaseDAO(String contextName) {
		super();
		this.contextName = contextName;
	}
	
	/**
	 * 从连接池中获取连接对象
	 */
	public Connection getConnection(){
		try {
			Context context = new InitialContext();
			DataSource ds = (DataSource) context.lookup("java:comp/env/" + contextName);
			Connection conn = ds.getConnection();
			return conn;
		} catch (NamingException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 释放资源
	 * @param conn
	 * @param stmt
	 * @param rs
	 */
	public void close(Connection conn, 
			Statement stmt, ResultSet rs){
		if(rs != null){
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		
		if(stmt != null){
			try {
				stmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		
		if(conn != null){
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 释放资源
	 * @param conn
	 * @param stmt
	 */
	public void close(Connection conn, Statement stmt){
		close(conn, stmt, null);
	}
	
	/**
	 * 执行insert、update和delete操作
	 * 
	 * @param sql
	 * @param objects
	 */
	public void executeUpdate(String sql, Object...params){
		Connection conn = getConnection();
		PreparedStatement stmt = null;
		if(conn != null){
			try {
				stmt = conn.prepareStatement(sql);
				bindParameters(stmt, params);
				//执行sql语句
				stmt.executeUpdate();
			} catch (SQLException e) {
				e.printStackTrace();
			} finally {
				close(conn, stmt);
			}
		}
	}

	/**
	 * 查询
	 * @param sql
	 * @param rowMapper 用于子类将ResultSet中的一行转换成JavaBean对象
	 * @param params
	 * @return
	 */
	public <T> List<T> executeQuery(String sql, 
			RowMapper<T> rowMapper, Object...params){
		Connection conn = getConnection();
		PreparedStatement stmt = null;
		ResultSet rs = null;
		try {
			stmt = conn.prepareStatement(sql);
			bindParameters(stmt, params);
			rs = stmt.executeQuery();
			//将rs中的记录转换成JavaBean对象
			if(rs != null){
				List<T> list = new ArrayList<T>();
				while(rs.next()){
					T t = rowMapper.mapper(rs);
					list.add(t);
				}
				return list;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally{
			close(conn, stmt, rs);
		}
		return null;
	}
	
	/**
	 * 根据id查询，只返回一个JavaBean对象
	 * @param sql
	 * @param rowMapper
	 * @param params
	 * @return
	 */
	public <T> T get(String sql, RowMapper<T> rowMapper,
			Object...params){
		List<T> list = executeQuery(sql, rowMapper, params);
		return list != null && list.size() > 0 ? list.get(0) : null;
	}
	
	/**
	 * 绑定参数
	 * @param stmt
	 * @param params
	 * @throws SQLException
	 */
	private void bindParameters(PreparedStatement stmt, Object... params) throws SQLException {
		//绑定参数
		if(params != null){
			for(int i = 0; i < params.length; i ++){
				stmt.setObject(i + 1, params[i]);
			}
		}
	}
}






